package com.kexio.file.entity;

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.kexio.common.entity.BaseEntity;

/**
 * 存储对象实体类
 * 
 * 对应数据库表 sys_storage_object
 * 存储文件的物理存储信息，支持去重和多存储后端
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@TableName("sys_storage_object")
public class StorageObject extends BaseEntity {
    
    /**
     * 存储对象ID（主键）- UUID字符串
     */
    @TableId(value = "id", type = IdType.ASSIGN_UUID)
    private String id;
    
    /**
     * 内容哈希值（SHA256）- 用于去重
     */
    @TableField("content_hash")
    private String contentHash;
    
    /**
     * 文件大小（字节）
     */
    @TableField("file_size")
    private Long fileSize;
    
    /**
     * 存储后端类型：LOCAL, MINIO, S3, OSS, COS等
     */
    @TableField("storage_type")
    private String storageType;
    
    /**
     * 存储桶/容器名称
     */
    @TableField("bucket_name")
    private String bucketName;
    
    /**
     * 存储路径/对象键
     */
    @TableField("storage_path")
    private String storagePath;
    
    /**
     * 存储URL（可选，用于CDN等）
     */
    @TableField("storage_url")
    private String storageUrl;
    
    /**
     * 存储配置名称（对应配置文件中的存储配置）
     */
    @TableField("storage_config")
    private String storageConfig;
    
    /**
     * 引用计数（有多少个FileInfo引用此存储对象）
     */
    @TableField("reference_count")
    private Integer referenceCount;
    
    /**
     * 存储状态：0-存储中，1-已存储，2-存储失败，3-已删除
     */
    @TableField("status")
    private Integer status;
    
    /**
     * 是否加密存储
     */
    @TableField("is_encrypted")
    private Boolean isEncrypted;
    
    /**
     * 加密算法（如果加密）
     */
    @TableField("encryption_algorithm")
    private String encryptionAlgorithm;
    
    /**
     * 加密密钥ID（如果使用KMS）
     */
    @TableField("encryption_key_id")
    private String encryptionKeyId;
    
    /**
     * 压缩算法（如果压缩）
     */
    @TableField("compression_algorithm")
    private String compressionAlgorithm;
    
    /**
     * 原始大小（压缩前，如果压缩）
     */
    @TableField("original_size")
    private Long originalSize;
    
    /**
     * 存储时间
     */
    @TableField("storage_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime storageTime;
    
    /**
     * 最后验证时间（完整性校验）
     */
    @TableField("last_verify_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastVerifyTime;
    
    /**
     * 验证状态：0-未验证，1-验证通过，2-验证失败
     */
    @TableField("verify_status")
    private Integer verifyStatus;
    
    /**
     * 存储元数据（JSON格式，存储后端特定信息）
     */
    @TableField("storage_metadata")
    private String storageMetadata;
    
    // ==================== 便捷方法 ====================
    
    /**
     * 判断存储对象是否有效（已存储且验证通过）
     */
    public boolean isValid() {
        return status != null && status == 1 && 
               (verifyStatus == null || verifyStatus == 0 || verifyStatus == 1);
    }
    
    /**
     * 判断是否已加密
     */
    public boolean isEncrypted() {
        return isEncrypted != null && isEncrypted;
    }
    
    /**
     * 判断是否已压缩
     */
    public boolean isCompressed() {
        return compressionAlgorithm != null && !compressionAlgorithm.isEmpty();
    }
    
    /**
     * 获取压缩率（如果压缩）
     */
    public double getCompressionRatio() {
        if (!isCompressed() || originalSize == null || originalSize <= 0 || fileSize == null || fileSize <= 0) {
            return 0.0;
        }
        return 1.0 - (fileSize.doubleValue() / originalSize.doubleValue());
    }
    
    /**
     * 增加引用计数
     */
    public void incrementReferenceCount() {
        if (referenceCount == null) {
            referenceCount = 1;
        } else {
            referenceCount++;
        }
    }
    
    /**
     * 减少引用计数
     */
    public void decrementReferenceCount() {
        if (referenceCount != null && referenceCount > 0) {
            referenceCount--;
        }
    }
    
    /**
     * 判断是否可以删除（引用计数为0）
     */
    public boolean canDelete() {
        return referenceCount == null || referenceCount <= 0;
    }
    
    // ==================== Getter/Setter ====================
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getContentHash() {
        return contentHash;
    }
    
    public void setContentHash(String contentHash) {
        this.contentHash = contentHash;
    }
    
    public Long getFileSize() {
        return fileSize;
    }
    
    public void setFileSize(Long fileSize) {
        this.fileSize = fileSize;
    }
    
    public String getStorageType() {
        return storageType;
    }
    
    public void setStorageType(String storageType) {
        this.storageType = storageType;
    }
    
    public String getBucketName() {
        return bucketName;
    }
    
    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }
    
    public String getStoragePath() {
        return storagePath;
    }
    
    public void setStoragePath(String storagePath) {
        this.storagePath = storagePath;
    }
    
    public String getStorageUrl() {
        return storageUrl;
    }
    
    public void setStorageUrl(String storageUrl) {
        this.storageUrl = storageUrl;
    }
    
    public String getStorageConfig() {
        return storageConfig;
    }
    
    public void setStorageConfig(String storageConfig) {
        this.storageConfig = storageConfig;
    }
    
    public Integer getReferenceCount() {
        return referenceCount;
    }
    
    public void setReferenceCount(Integer referenceCount) {
        this.referenceCount = referenceCount;
    }
    
    public Integer getStatus() {
        return status;
    }
    
    public void setStatus(Integer status) {
        this.status = status;
    }
    
    public Boolean getIsEncrypted() {
        return isEncrypted;
    }
    
    public void setIsEncrypted(Boolean isEncrypted) {
        this.isEncrypted = isEncrypted;
    }
    
    public String getEncryptionAlgorithm() {
        return encryptionAlgorithm;
    }
    
    public void setEncryptionAlgorithm(String encryptionAlgorithm) {
        this.encryptionAlgorithm = encryptionAlgorithm;
    }
    
    public String getEncryptionKeyId() {
        return encryptionKeyId;
    }
    
    public void setEncryptionKeyId(String encryptionKeyId) {
        this.encryptionKeyId = encryptionKeyId;
    }
    
    public String getCompressionAlgorithm() {
        return compressionAlgorithm;
    }
    
    public void setCompressionAlgorithm(String compressionAlgorithm) {
        this.compressionAlgorithm = compressionAlgorithm;
    }
    
    public Long getOriginalSize() {
        return originalSize;
    }
    
    public void setOriginalSize(Long originalSize) {
        this.originalSize = originalSize;
    }
    
    public LocalDateTime getStorageTime() {
        return storageTime;
    }
    
    public void setStorageTime(LocalDateTime storageTime) {
        this.storageTime = storageTime;
    }
    
    public LocalDateTime getLastVerifyTime() {
        return lastVerifyTime;
    }
    
    public void setLastVerifyTime(LocalDateTime lastVerifyTime) {
        this.lastVerifyTime = lastVerifyTime;
    }
    
    public Integer getVerifyStatus() {
        return verifyStatus;
    }
    
    public void setVerifyStatus(Integer verifyStatus) {
        this.verifyStatus = verifyStatus;
    }
    
    public String getStorageMetadata() {
        return storageMetadata;
    }
    
    public void setStorageMetadata(String storageMetadata) {
        this.storageMetadata = storageMetadata;
    }
    
    @Override
    public String toString() {
        return "StorageObject{" +
                "id='" + id + '\'' +
                ", contentHash='" + contentHash + '\'' +
                ", fileSize=" + fileSize +
                ", storageType='" + storageType + '\'' +
                ", bucketName='" + bucketName + '\'' +
                ", storagePath='" + storagePath + '\'' +
                ", storageConfig='" + storageConfig + '\'' +
                ", referenceCount=" + referenceCount +
                ", status=" + status +
                ", isEncrypted=" + isEncrypted +
                ", storageTime=" + storageTime +
                ", verifyStatus=" + verifyStatus +
                '}';
    }
}
